/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package javaapplication3;

import gdr.maps.MapPaths;
import java.awt.Point;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.Vector;
import javax.swing.ImageIcon;


/**
 *
 * @author iamdelac
 */
public class Player extends javax.swing.JLabel implements Runnable{

    protected final String STAND="/player/stand/";
    protected final String WALK="/player/walk/";
    protected final String ATTACK="/player/attack/";
    public String nome_player;
    private Vector <javax.swing.ImageIcon[]> sprites;
    private int  offset_x;
    private int  offset_y;
    protected String stato;
    private String orientation;
    protected Thread thread;
    protected Timer timer_azione;
    protected Point punto_destinazione;
    protected int distanza_destinazione;
    protected Player nemicoFocused;
    private int frameAttack;




/**
 * <pre>
 *@param posizione (left || right)
 *@param nome_fighter
 </pre>

 */
    public Player (String nome_fighter) {
       super();
       timer_azione = new Timer();
       sprites = new Vector();
       this.setDoubleBuffered(true);
       this.nome_player = nome_fighter;
       this.orientation = "n/";
       punto_destinazione = new Point();
       stato = STAND;
       cambiaAnimazione(STAND);
       }


public void cambiaAnimazione(String animazione){
             offset_x = 46; // devono puntare ai piedi
             offset_y = 74;
             Vector <javax.swing.ImageIcon[]> sprites_temp = new Vector <javax.swing.ImageIcon[]>();
             for (File file : new File ( getClass().getResource(stato+orientation).getFile()).listFiles(new ImageFileFilter()) )
             {
              try {//carico in memoria tutte le immagini di un' azione per tutti gli orientamenti
                String[] path = file.getCanonicalPath().split("/");
                String nameFile = path[path.length-1];
                javax.swing.ImageIcon[] orientations = new javax.swing.ImageIcon[8];
                orientations[0] = new javax.swing.ImageIcon(getClass().getResource(stato+"n/"+nameFile));
                orientations[1] = new javax.swing.ImageIcon(getClass().getResource(stato+"ne/"+nameFile));
                orientations[2] = new javax.swing.ImageIcon(getClass().getResource(stato+"e/"+nameFile));
                orientations[3] = new javax.swing.ImageIcon(getClass().getResource(stato+"se/"+nameFile));
                orientations[4] = new javax.swing.ImageIcon(getClass().getResource(stato+"s/"+nameFile));
                orientations[5] = new javax.swing.ImageIcon(getClass().getResource(stato+"sw/"+nameFile));
                orientations[6] = new javax.swing.ImageIcon(getClass().getResource(stato+"w/"+nameFile));
                orientations[7] = new javax.swing.ImageIcon(getClass().getResource(stato+"nw/"+nameFile));
                sprites_temp.add(orientations);
                  }
               catch (IOException ex) {ex.printStackTrace();}
               sprites = sprites_temp;
             }
            setSize(sprites_temp.get(0)[0].getIconWidth(), sprites.get(0)[0].getIconHeight());

}


public  void muovi(Point lastPoint, int distanza){
      nemicoFocused=null; //se clicko da qualche parte lascia stare l'azione precedente e va la
      cammina(lastPoint, distanza);
}


public void riceviColpo(Point colpo){
    if ((stato.equals(STAND)||stato.equals(WALK)) && getLocation().distance(colpo)<=40)
        {stato=STAND;
         Player_task colpito = new Player_task(3,null);
         timer_azione.schedule(colpito, 0);
        }
}

public void cammina(Point lastPoint, int distanza){
    MapPaths map =MainForm.getInstance().getMap();
      java.util.ArrayList<String> path = map.calcolaPath(map.getRombo(getLocation().x, getLocation().y), map.getRombo(lastPoint.x, lastPoint.y));
      System.out.println(map.getRombo(getLocation().x, getLocation().y));
      System.out.println(path);
       punto_destinazione = lastPoint;
       distanza_destinazione = distanza;
       Player_task muovi = new Player_task(0,path);
       timer_azione.schedule(muovi, 0);
}

public void attacca (Player nemico)
        {
         nemicoFocused = nemico;
         frameAttack=6;
         Timer timer = new Timer();
         Player_task attacca = new Player_task(1,null);
         timer.schedule(attacca, 0);
        }


        
public void setThread(Thread trd){
    this.thread = trd;
        }


public  void run (){
    String statoOld = stato;
    ImageIcon[] sprite;
    boolean oneCycle = false;
while (true)
     {
      
      for( int h=0; h<sprites.size();h++)
        { sprite = sprites.get(h);
          if (!statoOld.equals(stato))
              {
               statoOld = stato;
               cambiaAnimazione(stato);
               break;
              }
      	  if (orientation.equals("n/")) {this.setIcon(sprite[0]);}
          else{if (orientation.equals("ne/")) {this.setIcon(sprite[1]);}
          else{if (orientation.equals("e/")) {this.setIcon(sprite[2]);}
          else{if (orientation.equals("se/")) {this.setIcon(sprite[3]);}
          else{if (orientation.equals("s/")) {this.setIcon(sprite[4]);}
          else{if (orientation.equals("sw/")) {this.setIcon(sprite[5]);}
          else{if (orientation.equals("w/")) {this.setIcon(sprite[6]);}
          else{if (orientation.equals("nw/")) {this.setIcon(sprite[7]);}}}}}}}}  
      	  if (stato.equals(ATTACK) && h==frameAttack) {nemicoFocused.riceviColpo(getLocation());}
          try{thread.sleep(110);}catch(Exception ex){}
        }
      if (oneCycle)
              {
               oneCycle = false;
               if (stato.equals(ATTACK))
                   {stato=STAND;}
              }
          if (statoOld.equals(ATTACK))
              {
               oneCycle = true;
              }
      
                    }

}


/**<p>
 * @param azione
 * @param path
 *</p>
 *<p>
 * azione=0 --> muovi
 *</p>*/
      protected class Player_task extends java.util.TimerTask {

         int azione;
         java.util.ArrayList<String> path;

      public Player_task (int azione, java.util.ArrayList<String> path){
          super();
          this.azione = azione;
          this.path = path;
      }


      public void run(){

            if(azione==0) {perform_muovi(path);}
            if(azione==1) {perform_attacca();}
            if(azione==3) {perform_riceviColpo();}
                       }

      public void perform_segui()
       {
        if ((nemicoFocused!=null) && getLocation().distance(nemicoFocused.getLocation()) > 30)
          {
           cammina(nemicoFocused.getLocation(), 40);
           try{thread.sleep(400);}catch(Exception ex){} // gli do il tempo di farlo incamminare
           while(!stato.equals(STAND) && nemicoFocused != null)
            {
             try{thread.sleep(200);}catch(Exception ex){}
             if (nemicoFocused.getLocation().distance(punto_destinazione) >5)
                 {
                   cammina(nemicoFocused.getLocation(), 30);
                 }
            }
           if (nemicoFocused==null){System.out.println("basta attaccare!");}
           }
        }

      public void perform_attacca()
        {
         perform_segui();
         if (nemicoFocused!=null)
           {
            if(getLocation().distance(nemicoFocused.getLocation()) <= distanza_destinazione+30)
              {stato=ATTACK;
               while(!stato.equals(STAND)) { try{thread.sleep(100);}catch(Exception ex){}}
               try{thread.sleep(500);}catch(Exception ex){}
              }
            perform_attacca();
           }
        }
        

      public void perform_riceviColpo(){
          String statoOld=stato;
          setEnabled(false);
          stato=STAND;
          try{thread.sleep(1000);}catch(Exception ex){}
          setEnabled(true);
          riprendiAzioneVecchia(statoOld);
      }


      public void perform_muovi(java.util.ArrayList<String> path)
      {
        stato=WALK;
        javax.swing.ImageIcon romboImage = new javax.swing.ImageIcon(getClass().getResource(Constants.OCCUPATO));
        int altezza = romboImage.getIconHeight();
        int larghezza = romboImage.getIconWidth();
        Point destinazione = punto_destinazione;
        for (int i=1; i<path.size()-1; i++)
        {
         if (destinazione != punto_destinazione || !stato.equals(WALK)) {break;}
         int x_end = (larghezza/2) * ((Integer.parseInt(path.get(i)))/(Constants.righe/2));
         if (  ((Integer.parseInt(path.get(i))%Constants.righe)%2 != 0) )
             {x_end = x_end + larghezza/2;}
         int y_end = (altezza/2)+ ((altezza/2) * (Integer.parseInt(path.get(i))%Constants.righe));
         int x_start = getLocation().x;
         int y_start = getLocation().y;
         muoviPuntoPunto(new Point(x_start, y_start), new Point(x_end, y_end), 0);
        }
         if (destinazione == punto_destinazione)
           {System.out.println("ultimo punto "+punto_destinazione);
             muoviPuntoPunto(new Point(getLocation().x, getLocation().y), punto_destinazione, distanza_destinazione);
            stato=STAND;
           }
        
      }



      public void muoviPuntoPunto(Point start, Point end, int distanza)
        {
         Point destinazione = punto_destinazione;
         int new_x=start.x;
         int new_y=start.y;
         while (new Point(new_x,new_y ).distance(end)> distanza && (new_x != end.x || new_y != end.y)&& destinazione==punto_destinazione && stato.equals(WALK))
         {        

          orientation="";
          if (new_y < end.y)
           {
            new_y = new_y+1;
            orientation = "s";
            }
          else{
               if (new_y > end.y)
                {
                  new_y = new_y-1;
                  orientation = "n";
                 }
              }
          if (new_x < end.x)
             {
              new_x = new_x+1;
              orientation += "e";
             }
          else{
               if (new_x > end.x)
                 {
                   new_x = new_x-1;
                   orientation += "w";
                 }
              }
          orientation +="/";
          setLocation(new_x, new_y);
          try{thread.sleep(20);}catch(Exception ex){};
         }
        }
     }



      @Override
      public Point getLocation(){ 
          return new Point (super.getLocation().x+offset_x,super.getLocation().y+offset_y);
      }

      @Override
      public void setLocation(Point p){
          p.x = p.x - offset_x;
          p.y = p.y - offset_y;
         super.setLocation(p);
      }
       @Override
      public void setLocation(int x , int y){
          x = x - offset_x;
          y = y - offset_y;
         super.setLocation(x,y);
      }

       protected void riprendiAzioneVecchia(String statoOld){

          if (statoOld.equals(WALK)){cammina(punto_destinazione, distanza_destinazione);}
          if (statoOld.equals(ATTACK)) {attacca(nemicoFocused);}
       }

     
       
}
